package com.example.comm.util;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by bill on 2017/8/24.
 */

final public class BZJson {

    private static JsonObject parseJsonObject(String json) {
        JsonObject jsonObject;
        try {
            JsonParser parser = new JsonParser();
            jsonObject = parser.parse(json).getAsJsonObject();
        } catch (Exception ignore) {
            jsonObject = new JsonObject();
        }
        return jsonObject;
    }

    private static JsonArray parseJsonArray(String json) {
        JsonArray jsonArray;
        try {
            JsonParser parser = new JsonParser();
            jsonArray = parser.parse(json).getAsJsonArray();
        } catch (Exception ignore) {
            jsonArray = new JsonArray();
        }
        return jsonArray;
    }

    public static Map<String, Object> toMap(String json) {
        return toMap(parseJsonObject(json));
    }

    public static List<?> toList(String json) {
        return toList(parseJsonArray(json));
    }

    public static <T> T toAny(String json, TypeToken<T> typeToken) {
        return getGsonIfNeed().fromJson(json, typeToken.getType());
    }

    private static Map<String, Object> toMap(JsonObject json) {
        Map<String, Object> map = new HashMap<>();
        for (Map.Entry<String, JsonElement> entry : json.entrySet()) {
            String key = entry.getKey();
            JsonElement value = entry.getValue();
            if (value.isJsonArray()) {
                map.put(key, toList((JsonArray) value));
            } else if (value.isJsonObject()) {
                map.put(key, toMap((JsonObject) value));
            } else if (value.isJsonPrimitive()) {
                map.put(key, value.getAsString());
            } else if (value.isJsonNull()) {
                map.put(key, "");
            } else {
                map.put(key, value);
            }
        }
        return map;
    }

    private static List<Object> toList(JsonArray json) {
        List<Object> list = new ArrayList<>();
        int size = json.size();
        for (int i = 0; i < size; i++) {
            JsonElement value = json.get(i);
            if (value.isJsonArray()) {
                list.add(toList((JsonArray) value));
            } else if (value.isJsonObject()) {
                list.add(toMap((JsonObject) value));
            } else if (value.isJsonPrimitive()) {
                list.add(value.getAsString());
            } else if (value.isJsonNull()) {
                list.add("");
            } else {
                list.add(value);
            }
        }
        return list;
    }

    public static String decodeJson(Object content) {
        return getGsonIfNeed().toJson(content);
    }

    private static Gson mDecodeGson;


    private static Gson getGsonIfNeed() {
        if (mDecodeGson == null) {
            mDecodeGson = new GsonBuilder().enableComplexMapKeySerialization().create();
        }
        return mDecodeGson;
    }

}
